﻿//  --------------------------------
//  Copyright (c) AW Systems, Inc. All rights reserved.
//  This source code is made available under the terms of the Microsoft Public License (Ms-PL)
//  http://www.codeplex.com/SLAM/license
//  ---------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using Slam.Configuration;
using Slam.Data;
using Slam.Events;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace Slam.Activation
{
    /// <summary>
    /// The DataSynchronizer consists of the method by which SLAM can synchronize its data with its
    /// host SharePoint site.
    /// 
    /// DataSynchronizer is the default implementation of SLAM's IDataSynchronizer.  Synchronize calls
    /// the IDataSynchronizeTypeProcessor.Process method for each type configured to be managed by SLAM.
    /// By default Synchronize is called by the Activator.
    /// 
    /// </summary>
    public class DataSynchronizer : IDataSynchronizer
    {   
        #region Private State

        /// <summary>
        /// SLAM Configuration
        /// </summary>
        private IConfigurationManager _configuration;

        #endregion
        #region Constructors

        /// <summary>
        /// Creates instance of DataSynchronizer for the given Configuration.
        /// </summary>
        /// <param name="configuration"></param>
        public DataSynchronizer(IConfigurationManager configuration)
        {
            _configuration = configuration;
        }

        #endregion


        #region IDataSynchronizer Members

        /// <summary>
        /// Synchronizes data in the given SharePoint Site, by URL location, by getting all 
        /// all configured types from SLAM's configuration and calling the Process method for each
        /// type's mapped IDataSynchronizeTypeProcessor.  Process called from this method will not
        /// synchronize all data for each type but only the schema.
        /// </summary>
        /// <param name="sharepointSiteLocation">Full URL location for the SharePoint Site to synchronize</param>
        public void Synchronize(string sharepointSiteLocation)
        {
            //When processing, SharePoint events should not fire
            EventUtility eventUtility = new EventUtility();
            eventUtility.DisableEventHandlers();

            SPSite site = new SPSite(sharepointSiteLocation);

            string siteCollection = site.ServerRelativeUrl.TrimStart('/');
            DataMapping currentDataMapping = _configuration.DataMapping;
            if (!String.IsNullOrEmpty(siteCollection) && _configuration.DataMappings.ContainsKey(siteCollection))
            {
                currentDataMapping = _configuration.DataMappings[siteCollection];
            }

            foreach (ConfiguredType type in currentDataMapping.GetAllTypes())
            {
                string itemTypeName = type.Name;
                if (type is SqlConfiguredType)
                {
                    SqlConfiguredType sqlType = (SqlConfiguredType)type;
                    if (!String.IsNullOrEmpty(sqlType.Table))
                    {
                        itemTypeName = sqlType.Table;
                    }
                }

                //Get Processor for the type.  PopulateData is set to false because
                //this method is called on Activation.  A full synchronization of data should
                //not occur on Activation for concerns of timing out on large Lists.
                IDataSynchronizeTypeProcessor processor = ComponentService.GetInstance<IDataSynchronizeTypeProcessor>(type.SiteCollection, type.Site, type.Id, itemTypeName);
                processor.Process(sharepointSiteLocation, new Dictionary<string, object>() { { "ConfigType", type }, { "CreateTable", true }, { "PopulateData", false } });
            }

            site.Dispose();

            eventUtility.EnableEventHandlers();
        }

        #endregion
    }
}

